package zoran.wang.proxy;

import zoran.wang.utils.LogUtils;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * description：
 *
 * @author wangzhuo
 * @date 2022/3/19 19:25
 * @Email zoranwang@yeah.net
 */
public class CalculatorProxy {

    /**
     * jdk动态代理
     * 目的：动态修改class字节码
     * 功能：增强（前置增强、后置增强、异常增强、返回增强）
     *
     * @param target 目标方法
     * @return
     */
    public static Object createJdkProxyInstance(Object target) {

        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        LogUtils.logBefore(method.getName(), args);
                        Object result = null;

                        try {
                            if (args.length > 0) {
                                result = method.invoke(target, args);
                            } else {
                                result = method.invoke(target);
                            }
                            LogUtils.logAfterReturning(method.getName(), result);
                        } catch (Exception e) {
                            LogUtils.logAfterThrowing(method.getName(), e);
                            throw new RuntimeException(e);
                        }

                        return result;
                    }
                }
        );
    }

}
